package models

import (
	"gitee.com/tangrx/go-admin/utils"
	"log"
)

const CODE_TREE_SQL string = `WITH RECURSIVE T ( id, key, value, status, remark, name, type, parent_id, sort, 
       create_time, create_id, update_id, update_time, path, depth)  AS (
    SELECT   id, key, value, status, remark, name, type, parent_id, sort, 
       create_time, create_id, update_id, update_time, ARRAY[id] AS path, 1 AS depth
    FROM sys_code
    WHERE parent_id =0 
    UNION ALL 
    SELECT  D.id, D.key, D.value, D.status, D.remark, D.name, D.type, D.parent_id, D.sort, 
       D.create_time, D.create_id, D.update_id, D.update_time, T.path || D.id, T.depth + 1 AS depth
    FROM sys_code D
    JOIN T ON D.parent_id = T.id
    )`

func GetCodeList4Pager(form SearchForm) *PageResult {
	sqlWhere := " status = 0 and type <> 1" // status =1 的数据隐藏 type =1 表示目录分类
	key := form.GetStr("key")
	params := make([]interface{}, 0)
	i := 1
	if len(key) > 0 {
		params = append(params, "%"+form.GetStr("key")+"%")
		sqlWhere += " and (key like $" + utils.IntToStr(i) + " or value like $" + utils.IntToStr(i) +
			" or remark like $" + utils.IntToStr(i) + " or name like $" + utils.IntToStr(i) + ")"
		i++
	}
	parentId := form.GetInt("parent_id")
	if parentId != 0 {
		params = append(params, parentId)
		sqlWhere += " and ( path @> ARRAY[( $" + utils.IntToStr(i) + "::bigint )] and id  <> ( $" + utils.IntToStr(i) + "::bigint )  )"
		i++
	}

	strSqlPre := CODE_TREE_SQL

	return PageHavePre("", strSqlPre, "*", "T", sqlWhere, "sort", form.Page, params...)
}

// 查询分组树型列表
func GetCodeTree(form SearchForm) *[]interface{} {
	dataList := make([]interface{}, 0)                                  // 返回值
	params := make([]interface{}, 0)                                    // 参数
	sqlList := "select * from sys_code where type =1  and  status = 0 " // status =1 的数据隐藏 type =1 表示目录分类
	db, err := OpenDB()
	defer db.Close()
	if err != nil {
		log.Fatalln(err)
		return &dataList
	}
	log.Println(sqlList)
	sqlList += " order by sort"
	rows, err1 := db.Queryx(sqlList, params...)
	if err1 != nil {
		log.Fatalln(err1)
		return &dataList
	}

	for rows.Next() {
		data := make(map[string]interface{})
		rows.MapScan(data)
		dataList = append(dataList, data)
	}
	return &dataList
}

// 查询是否有子节点
func GetTreeNode(id int64) (result int) {
	sqlCheck := "select count(1) from sys_code where  parent_id=$1"
	db, _ := OpenDB()
	defer db.Close()
	err := db.Get(&result, sqlCheck, id)
	if err != nil {
		log.Fatal(err)
		result = -1
	}
	return
}

// 删除
func DeleteCode(id int64) int64 {
	sqlSave := "delete from sys_code  where id=:id"
	db, _ := OpenDB()
	defer db.Close()
	param := map[string]interface{}{"id": id}
	result, err := db.NamedExec(sqlSave, param)
	if err != nil {
		log.Fatalln(err)
		return 0
	} else {
		i, _ := result.RowsAffected()
		return i
	}
}

// 检查key 是否重复
func CheckNodeByKey(key string, id int64) (result int) {
	sqlCheck := "select count(1) from sys_code where  id != $1 and key = $2 "
	db, _ := OpenDB()
	defer db.Close()
	err := db.Get(&result, sqlCheck, id, key)
	if err != nil {
		log.Fatal(err)
		result = -1
	}
	return
}

// 检查父节点是否合法
func CheckParentId(id int64, pid int64) (result bool) {
	if pid == 0 {
		return true
	}
	if pid == id {
		return false
	}
	strSql := CODE_TREE_SQL
	strSql += "  select count(1)  from t where  id = ( $2::bigint ) and ( path @> ARRAY[( $1::bigint )] and id  <> ( $1::bigint )  )  "
	db, _ := OpenDB()
	defer db.Close()
	var count int64
	err := db.Get(&count, strSql, id, pid)
	if err != nil {
		log.Fatal(err)
		result = false
	}
	return count == 0
}

// 添加用户
func AddCodeData(code *Code) int64 {
	sqlSave := `
		INSERT INTO sys_code(key, value, status, remark, name, type, parent_id, sort, 
       create_time, create_id, update_id, update_time) 
		VALUES (:key, :value, :status, :remark, :name, :type, :parent_id, :sort, 
		        CURRENT_TIMESTAMP, :create_id, :update_id,CURRENT_TIMESTAMP)`
	db, _ := OpenDB()
	defer db.Close()
	result, err := db.NamedExec(sqlSave, code)
	if err != nil {
		log.Fatalln(err)
		return 0
	} else {
		i, _ := result.RowsAffected()
		return i
	}
}

// 更新
func UpdateCode(code *Code) int64 {
	sqlSave := `update sys_code 
set key=:key,
value=:value,
status=:status,
remark=:remark,
name=:name,
type=:type,
parent_id=:parent_id,
sort=:sort, 
update_id=:update_id,
update_time=CURRENT_TIMESTAMP where id=:id`
	db, _ := OpenDB()
	defer db.Close()
	result, err := db.NamedExec(sqlSave, code)
	if err != nil {
		log.Fatalln(err)
		return 0
	} else {
		i, _ := result.RowsAffected()
		return i
	}
}
